#include "redisclient.h"
#include <boost/lexical_cast.hpp>
namespace TinyRPC{

bool RedisClient::redisCommandSuccess(redisContext *c, const char *format, ...){
    va_list argp;
    va_start(argp, format);
    redisReply *reply = (redisReply *)redisCommand(c, format,argp);
    va_end (argp);

    bool success = false;
    if (reply!=NULL && reply->type!=REDIS_REPLY_ERROR) {
        success = true;
    }
    freeReplyObject(reply);
    return success;
}

std::vector<std::string> RedisClient::redisCommandArray(redisContext *c, const char *format, ...){
    va_list argp;
    va_start(argp, format);
    redisReply *reply = (redisReply *)redisCommand(c, format,argp);
    va_end (argp);

    std::vector<std::string> result;
    bool success = false;
    if (reply!=NULL && reply->type==REDIS_REPLY_ARRAY) {
        success = true;

        for (int i=0; i<reply->elements; ++i) {
            result.push_back(reply->element[i]->str);
        }

    }
    freeReplyObject(reply);
    return result;
}

bool RedisClient::set(const std::string& key, const std::string& value){
    std::string cmd = "SET";
    cmd += " " + key;
    cmd += " " + value;
    // redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    // return true;
    return redisCommandSuccess(m_context, cmd.c_str());
}

bool RedisClient::setex(const std::string&  key, int seconds , const std::string&value ){
    std::string cmd = "SETEX";
    cmd += " " + key;
    cmd += " " + boost::lexical_cast<std::string>(seconds);
    cmd += " " + value;
    // redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    // return true;
    return redisCommandSuccess(m_context, cmd.c_str());
}
std::string RedisClient::get(const std::string& key){
    std::string cmd = "GET";
    cmd += " " + key;
    
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    return reply->str;
}
bool RedisClient::incr(const std::string& key){
    std::string cmd = "INCR";
    cmd += " " + key;
    
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    return true;
}
bool RedisClient::incrby(const std::string& key, long increment ){
    std::string cmd = "incrby";
    cmd += " " + key;
    cmd += " " + boost::lexical_cast<std::string>(increment);
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    return true;
}
bool RedisClient::incrbyfloat (const std::string&  key, float increment){
    std::string cmd = "incrbyfloat";
    cmd += " " + key;
    cmd += " " + boost::lexical_cast<std::string>(increment);
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    return true;
}

// key的一些操作
bool RedisClient::expire(const std::string& key , int seconds){
    //  "expire TinyRPC:EchoServiceRpc:127.0.0.1:8081 600"
    std::string cmd = "expire";
    cmd += " " + key;
    cmd += " " + boost::lexical_cast<std::string>(seconds);
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    return true;
    //return redisCommandSuccess(m_context, cmd.c_str());
}

bool RedisClient::exists (const std::string& key){
    std::string cmd = "exists";
    cmd += " " + key;
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    return true;
}


bool RedisClient::rpush(const std::string& key, const std::string& value){
    std::string cmd = "rpush";
    cmd += " " + key;
    cmd += " " + value;
    redisReply *reply = (redisReply *)redisCommand(m_context, cmd.c_str());
    freeReplyObject(reply);
    return true;
}



// hash 操作

bool RedisClient::hset(const std::string& key, const std::string& field, const std::string& value){
    std::string cmd = "hset";
    cmd += " " + key;
    cmd += " " + field;
    cmd += " " + value;
    return redisCommandSuccess(m_context, cmd.c_str());
}

bool RedisClient::hdel(const std::string& key, const std::string& field){
    std::string cmd = "hdel";
    cmd += " " + key;
    cmd += " " + field;
    return redisCommandSuccess(m_context, cmd.c_str());
}

std::vector<std::string> RedisClient::hgetall(const std::string& key){
    std::string cmd = "hgetall";
    cmd += " " + key;
    return redisCommandArray(m_context, cmd.c_str());
}

    
}